package cn.wokoba.dao.adapter.repository;

import cn.wokoba.dao.dao.ICrowdTagsDao;
import cn.wokoba.dao.dao.ICrowdTagsDetailDao;
import cn.wokoba.dao.dao.ICrowdTagsJobDao;
import cn.wokoba.dao.dao.po.CrowdTags;
import cn.wokoba.dao.dao.po.CrowdTagsDetail;
import cn.wokoba.dao.dao.po.CrowdTagsJob;
import cn.wokoba.dao.redis.RedissonService;
import cn.wokoba.service.tag.adapter.repository.ITagRepository;
import cn.wokoba.service.tag.model.entity.CrowdTagsJobEntity;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBitSet;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.support.TransactionTemplate;

@Repository
@Slf4j
public class TagRepository implements ITagRepository {
    @Resource
    private ICrowdTagsDao crowdTagsDao;
    @Resource
    private ICrowdTagsDetailDao crowdTagsDetailDao;
    @Resource
    private ICrowdTagsJobDao crowdTagsJobDao;

    @Resource
    private RedissonService redisService;

    @Resource
    TransactionTemplate transactionTemplate;

    @Override
    public CrowdTagsJobEntity queryCrowdTagsJobEntity(String tagId, String batchId) {
        LambdaQueryWrapper<CrowdTagsJob> crowdTagsJobLambdaQueryWrapper = Wrappers.<CrowdTagsJob>lambdaQuery();
        crowdTagsJobLambdaQueryWrapper.eq(CrowdTagsJob::getTagId, tagId)
                .eq(CrowdTagsJob::getBatchId, batchId);
        CrowdTagsJob crowdTagsJobRes = crowdTagsJobDao.selectOne(crowdTagsJobLambdaQueryWrapper);
        return null == crowdTagsJobRes ? null : CrowdTagsJobEntity.builder()
                .tagType(crowdTagsJobRes.getTagType())
                .tagRule(crowdTagsJobRes.getTagRule())
                .statStartTime(crowdTagsJobRes.getStatStartTime())
                .statEndTime(crowdTagsJobRes.getStatEndTime())
                .build();
    }

    @Override
    public void addCrowdTagsUserId(String tagId, String userId) {
        transactionTemplate.execute(status -> {
            try {
                CrowdTagsDetail crowdTagsDetail = new CrowdTagsDetail();
                crowdTagsDetail.setTagId(tagId);
                crowdTagsDetail.setUserId(userId);

                crowdTagsDetailDao.insert(crowdTagsDetail);

                // 获取BitSet
                RBitSet bitSet = redisService.getBitSet(tagId);
                bitSet.set(redisService.getIndexFromUserId(userId), true);
            } catch (DuplicateKeyException ignore) {
                status.setRollbackOnly();
                log.error("唯一索引冲突:",ignore);
                throw new RuntimeException(ignore);
            }
            return 0;
        });
    }

    @Override
    public void updateCrowdTagsStatistics(String tagId, int count) {
        CrowdTags crowdTags = new CrowdTags();
        crowdTags.setTagId(tagId);
        crowdTags.setStatistics(count);

        crowdTagsDao.updateCrowdTagsStatistics(crowdTags);
    }
}
